package com.basin.micro.auth.component;

import com.basin.common.core.exception.BasinException;
import jakarta.annotation.PostConstruct;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * @author: Sam ZHONG | sammy1997@aliyun.com
 */
@Component
@Slf4j
@Data
@RefreshScope
public class RsaCoder {
    @Value(value = "${private-key}")
    private String privateKey;
    @Value(value = "${public-key}")
    private String publicKey;

    @PostConstruct
    private void init() {
        // 添加Bouncy Castle作为安全提供者
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 解密
     *
     * @param encode 加密密码
     * @return 解密数据
     */
    public String decode(String encode) {
        try {
            byte[] decode = Base64.getDecoder().decode(this.privateKey);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decode);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encode));
            return new String(decryptedBytes);
        } catch (Exception e) {
            log.error("Failed to decode data", e);
            throw new BasinException("数据解析出错");
        }
    }

    /**
     * 加密
     *
     * @param decode 明文
     * @return 密文
     */
    public String encode(String decode) {
        try {
            byte[] decodedPublicKey = Base64.getDecoder().decode(this.publicKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedPublicKey);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedBytes = cipher.doFinal(decode.getBytes());
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            log.error("Failed to decode data", e);
            throw new BasinException("数据解析出错");
        }
    }

    /**
     * 解密对比
     *
     * @param encode1 encode1
     * @param encode2 encode2
     * @return 结果
     */
    public boolean isEqual(String encode1, String encode2) {
        return this.decode(encode1).equals(this.decode(encode2));
    }
}
